package kr.co.goodwilldd.framework.mybatis;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * Database Vendor 설정
 * 
 * <pre>
 * classpth:/properties/vendor.xml 참고
 * </pre>
 * 
 * @author GoodwillDD (kr.goodwilldd@gmail.com)
 *
 */
public class CustomVendorDatabaseIDProvider implements DatabaseIdProvider {

	private static final Logger logger = LoggerFactory
			.getLogger(CustomVendorDatabaseIDProvider.class);

	private Properties properties;

	@Override
	public void setProperties(Properties p) {
		this.properties = p;
	}

	@Override
	public String getDatabaseId(DataSource dataSource) throws SQLException {
		if (dataSource == null)
			throw new NullPointerException("dataSource cannot be null");
		try {
			return getDatabaseName(dataSource);
		} catch (Exception e) {
			logger.error("Could not get a databaseId from dataSource", e);
		}
		return null;
	}

	private String getDatabaseName(DataSource dataSource) throws SQLException {
		String productName = getDatabaseProductName(dataSource);
		if (this.properties != null) {
			for (Map.Entry<Object, Object> property : properties.entrySet()) {
				if (productName.contains((String) property.getKey())) {
					if ( logger.isDebugEnabled() )
						logger.info("DatabaseName is [{}]", (String) property.getValue());
					return (String) property.getValue();
				}
			}
			return null;
		}
		return productName;
	}

	private String getDatabaseProductName(DataSource dataSource)
			throws SQLException {
		Connection con = null;
		try {
			con = dataSource.getConnection();
			DatabaseMetaData metaData = con.getMetaData();
			
			if ( logger.isDebugEnabled() )
				logger.info("DatabaseName ProductName is [{}]", metaData.getDatabaseProductName());
			
			return metaData.getDatabaseProductName();
		} finally {
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
				}
			}
		}
	}

}
